home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktimeintro / createmovie / application files / comapplication.c next >
Encoding:
Text File  |  2000-10-06  |  16.1 KB  |  627 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //
  7. //    Written by:    Tim Monroe
  8. //                Based on the QTShell code written by Tim Monroe, which in turn was based on the MovieShell
  9. //                code written by Kent Sandvik (Apple DTS). This current version is now very far removed from
  10. //                MovieShell.
  11. //
  12. //    Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  13. //
  14. //    Change History (most recent first):
  15. //       
  16. //       <2>         03/02/00    rtm        made changes to get things running under CarbonLib
  17. //       <1>         11/05/99    rtm        first file
  18. //
  19. //////////
  20.  
  21. //////////
  22. //
  23. // header files
  24. //
  25. //////////
  26.  
  27. #include "ComApplication.h"
  28.  
  29.  
  30. //////////
  31. //
  32. // global variables
  33. //
  34. //////////
  35.  
  36. #if TARGET_OS_MAC
  37. AEEventHandlerUPP        gHandleOpenAppAEUPP;                    // UPPs for our Apple event handlers
  38. AEEventHandlerUPP        gHandleOpenDocAEUPP;
  39. AEEventHandlerUPP        gHandlePrintDocAEUPP;
  40. AEEventHandlerUPP        gHandleQuitAppAEUPP;
  41. extern Boolean            gAppInForeground;                        // is our application in the foreground?    
  42. #endif
  43.  
  44. #if TARGET_OS_WIN32
  45. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  46. #endif
  47.  
  48.  
  49. //////////
  50. //
  51. // QTApp_Init
  52. // Do any application-specific initialization.
  53. //
  54. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  55. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  56. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  57. //
  58. //////////
  59.  
  60. void QTApp_Init (UInt32 theStartPhase)
  61. {
  62.     // do any start-up activities that should occur before the MDI frame window is created
  63.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  64. #if TARGET_OS_MAC
  65.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  66.         QTApp_InstallAppleEventHandlers();
  67. #endif
  68.     }
  69.  
  70.     // do any start-up activities that should occur after the MDI frame window is created
  71.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  72. #if TARGET_OS_WIN32
  73.         // on Windows, open as movie documents any files specified on the command line
  74.         SendMessage(ghWnd, WM_OPENDROPPEDFILES, 0L, 0L);
  75. #endif
  76.     }
  77. }
  78.  
  79.  
  80. //////////
  81. //
  82. // QTApp_Stop
  83. // Do any application-specific shut-down.
  84. //
  85. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  86. // *before* any open movie windows are destroyed or *after*.
  87. //
  88. //////////
  89.  
  90. void QTApp_Stop (UInt32 theStopPhase)
  91. {    
  92.     // do any shut-down activities that should occur before the movie windows are destroyed
  93.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows) {
  94.         
  95.     }
  96.     
  97.     // do any shut-down activities that should occur after the movie windows are destroyed
  98.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  99. #if TARGET_OS_MAC
  100.         // dispose of routine descriptors for Apple event handlers
  101.         DisposeAEEventHandlerUPP(gHandleOpenAppAEUPP);
  102.         DisposeAEEventHandlerUPP(gHandleOpenDocAEUPP);
  103.         DisposeAEEventHandlerUPP(gHandlePrintDocAEUPP);
  104.         DisposeAEEventHandlerUPP(gHandleQuitAppAEUPP);
  105. #endif
  106.     
  107.     }
  108. }
  109.  
  110.  
  111. //////////
  112. //
  113. // QTApp_Idle
  114. // Do any processing that can/should occur at idle time.
  115. //
  116. //////////
  117.  
  118. void QTApp_Idle (WindowReference theWindow)
  119. {
  120.     WindowObject         myWindowObject = NULL;
  121.     GrafPtr             mySavedPort;
  122.     
  123.     GetPort(&mySavedPort);
  124.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  125.     
  126.     myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow);
  127.     if (myWindowObject != NULL) {
  128.         MovieController        myMC = NULL;
  129.     
  130.         myMC = (**myWindowObject).fController;
  131.         if (myMC != NULL) {
  132.             
  133.             // run any idle-time tasks for the movie
  134.             
  135. #if TARGET_OS_MAC
  136.             // restore the cursor to the arrow
  137.             // if it's outside the front movie window or outside the window's visible region
  138.             if (theWindow == QTFrame_GetFrontMovieWindow()) {
  139.                 Rect            myRect;
  140.                 Point            myPoint;
  141.                 RgnHandle        myVisRegion;
  142.                 Cursor            myArrow;
  143.                 
  144.                 GetMouse(&myPoint);
  145.                 myVisRegion = NewRgn();
  146.                 GetPortVisibleRegion(QTFrame_GetPortFromWindowReference(theWindow), myVisRegion);
  147.                 GetWindowPortBounds(theWindow, &myRect);
  148.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, myVisRegion))
  149.                     MacSetCursor(GetQDGlobalsArrow(&myArrow));
  150.                     
  151.                 DisposeRgn(myVisRegion);
  152.  
  153.             }
  154. #endif // TARGET_OS_MAC
  155.         }
  156.     }
  157.     
  158.     // ***insert application-specific idle-time processing here***
  159.     
  160.     MacSetPort(mySavedPort);
  161. }
  162.  
  163.  
  164. //////////
  165. //
  166. // QTApp_Draw
  167. // Update the specified window.
  168. //
  169. //////////
  170.  
  171. void QTApp_Draw (WindowReference theWindow, Rect *theRefreshArea)
  172. {
  173. #pragma unused(theRefreshArea)
  174.  
  175.     GrafPtr             mySavedPort;
  176.     
  177.     GetPort(&mySavedPort);
  178.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  179.     
  180.     BeginUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  181.     //EraseRect(theRefreshArea);        // this is important only for non-rectangular movies
  182.     
  183.     // ***insert application-specific drawing here***
  184.     
  185.     // draw the movie controller and its movie
  186.     MCDoAction(QTFrame_GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  187.     
  188.     EndUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  189.     MacSetPort(mySavedPort);
  190. }
  191.  
  192.  
  193. //////////
  194. //
  195. // QTApp_HandleContentClick
  196. // Handle mouse button clicks in the specified window.
  197. //
  198. //////////
  199.  
  200. void QTApp_HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  201. {
  202. #pragma unused(theEvent)
  203.  
  204.     GrafPtr             mySavedPort;
  205.     
  206.     GetPort(&mySavedPort);
  207.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  208.     
  209.     // ***insert application-specific content-click processing here***
  210.  
  211.     MacSetPort(mySavedPort);
  212. }
  213.  
  214.  
  215. //////////
  216. //
  217. // QTApp_HandleKeyPress
  218. // Handle application-specific key presses.
  219. // Returns true if the key press was handled, false otherwise.
  220. //
  221. //////////
  222.  
  223. Boolean QTApp_HandleKeyPress (char theCharCode)
  224. {
  225.     Boolean        isHandled = true;
  226.     
  227.     switch (theCharCode) {
  228.     
  229.         // ***insert application-specific key-press processing here***
  230.  
  231.         default:
  232.             isHandled = false;
  233.             break;
  234.     }
  235.  
  236.     return(isHandled);
  237. }
  238.  
  239.  
  240. //////////
  241. //
  242. // QTApp_HandleMenu
  243. // Handle selections in the application's menus.
  244. //
  245. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  246. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window procedure.
  247. // When called from MacOS, theMenuItem is constructed like this:
  248. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  249. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  250. // In this way, we can simplify the menu-handling code. There are, however, some limitations, mainly that
  251. // the menu item identifiers on Windows must be derived from the Mac values. 
  252. //
  253. //////////
  254.  
  255. Boolean QTApp_HandleMenu (UInt16 theMenuItem)
  256. {
  257.     WindowObject        myWindowObject = NULL;
  258.     MovieController     myMC = NULL;
  259.     Movie                 myMovie = NULL;
  260.     Boolean                myIsHandled = false;            // false => allow caller to process the menu item
  261.     
  262.     myWindowObject = QTFrame_GetWindowObjectFromFrontWindow();
  263.     if (myWindowObject != NULL) {
  264.         myMC = (**myWindowObject).fController;
  265.         myMovie = (**myWindowObject).fMovie;
  266.     }
  267.     
  268.     // make sure we have a valid movie controller
  269.     if (myMC == NULL)
  270.         return(myIsHandled);
  271.  
  272.     switch (theMenuItem) {
  273.     
  274.         case IDM_CONTROLLER:
  275.             QTUtils_ToggleControllerBar(myMC);
  276.             myIsHandled = true;
  277.             break;
  278.  
  279.         case IDM_SPEAKER_BUTTON:
  280.             QTUtils_ToggleControllerButton(myMC, kQTUtilsSpeakerButton);
  281.             myIsHandled = true;
  282.             break;
  283.             
  284.         default:
  285.             break;
  286.             
  287.     } // switch (theMenuItem)
  288.     
  289.     return(myIsHandled);
  290. }
  291.  
  292.  
  293. //////////
  294. //
  295. // QTApp_AdjustMenus
  296. // Adjust state of items in the application's menus.
  297. //
  298. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  299. //
  300. //////////
  301.  
  302. void QTApp_AdjustMenus (WindowReference theWindow, MenuReference theMenu)
  303. {
  304. #if TARGET_OS_MAC
  305. #pragma unused(theMenu)
  306. #endif
  307.  
  308.     WindowObject        myWindowObject = NULL; 
  309.     MovieController     myMC = NULL;
  310.     MenuReference        myMenu;
  311.     
  312. #if TARGET_OS_WIN32
  313.     myMenu = theMenu;
  314. #endif
  315. #if TARGET_OS_MAC
  316.     myMenu = GetMenuHandle(kTestMenuResID);
  317. #endif
  318.     
  319.     if (theWindow != NULL)
  320.         myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow);
  321.  
  322.     if (myWindowObject != NULL)
  323.         myMC = (**myWindowObject).fController;
  324.  
  325.     // ***insert application-specific menu adjusting here***
  326.  
  327.     if (myMC == NULL) {
  328.         // no movie controller, so disable all the Test menu items
  329.         QTFrame_SetMenuItemState(myMenu, IDM_CONTROLLER, kDisableMenuItem);
  330.         QTFrame_SetMenuItemState(myMenu, IDM_SPEAKER_BUTTON, kDisableMenuItem);
  331.     } else {
  332.         // we've got a movie controller, so it's safe to proceed....
  333.         QTFrame_SetMenuItemState(myMenu, IDM_CONTROLLER, kEnableMenuItem);
  334.  
  335.         // if controller bar is visible, enable Test menu items
  336.         if (QTUtils_IsControllerBarVisible(myMC)) {
  337.             QTFrame_SetMenuItemLabel(myMenu, IDM_CONTROLLER, "Hide &Controller");
  338.                // ungray the other menu items
  339.             QTFrame_SetMenuItemState(myMenu, IDM_SPEAKER_BUTTON, kEnableMenuItem);
  340.             
  341.             // handle Test menu items
  342.             if (QTUtils_IsControllerButtonVisible(myMC, kQTVRSpeakerButton))
  343.                 QTFrame_SetMenuItemLabel(myMenu, IDM_SPEAKER_BUTTON, "Hide Spea&ker Button");
  344.             else 
  345.                 QTFrame_SetMenuItemLabel(myMenu, IDM_SPEAKER_BUTTON, "Show Spea&ker Button");
  346.             
  347.         } else {
  348.             // controller bar is not visible
  349.             
  350.             QTFrame_SetMenuItemLabel(myMenu, IDM_CONTROLLER, "Show &Controller");
  351.               // gray the other menu items
  352.             QTFrame_SetMenuItemState(myMenu, IDM_SPEAKER_BUTTON, kDisableMenuItem);
  353.         }
  354.     }
  355. }
  356.  
  357.  
  358. //////////
  359. //
  360. // QTApp_HandleEvent
  361. // Perform any application-specific event loop actions.
  362. //
  363. // Return true to indicate that we've completely handled the event here, false otherwise.
  364. //
  365. //////////
  366.  
  367. Boolean QTApp_HandleEvent (EventRecord *theEvent)
  368. {
  369. #pragma unused(theEvent)
  370.  
  371.     // ***insert application-specific event handling here***
  372.     
  373.     return(false);            // no-op for now
  374. }
  375.  
  376.  
  377. //////////
  378. //
  379. // QTApp_SetupController
  380. // Configure the movie controller.
  381. //
  382. //////////
  383.  
  384. void QTApp_SetupController (MovieController theMC)
  385. {
  386.     long            myControllerFlags;
  387.     
  388.     // CLUT table use
  389.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  390.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  391.  
  392.     // enable keyboard event handling
  393.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  394.     
  395.     // disable drag support
  396.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  397. }
  398.  
  399.  
  400. //////////
  401. //
  402. // QTApp_SetupWindowObject
  403. // Do any application-specific initialization of the window object.
  404. //
  405. //////////
  406.  
  407. void QTApp_SetupWindowObject (WindowObject theWindowObject)
  408. {
  409. #pragma unused(theWindowObject)
  410.  
  411.     // ***insert application-specific window object configuration here***
  412. }
  413.  
  414.  
  415. //////////
  416. //
  417. // QTApp_RemoveWindowObject
  418. // Do any application-specific clean-up of the window object.
  419. //
  420. //////////
  421.  
  422. void QTApp_RemoveWindowObject (WindowObject theWindowObject)
  423. {
  424. #pragma unused(theWindowObject)
  425.     
  426.     // ***insert application-specific window object clean-up here***
  427.  
  428.     // QTFrame_DestroyMovieWindow in MacFramework.c or QTFrame_MovieWndProc in WinFramework.c
  429.     // releases the window object itself
  430. }
  431.  
  432.  
  433. //////////
  434. //
  435. // QTApp_MCActionFilterProc 
  436. // Intercept some actions for the movie controller.
  437. //
  438. // NOTE: The theRefCon parameter is a handle to a window object record.
  439. //
  440. //////////
  441.  
  442. PASCAL_RTN Boolean QTApp_MCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  443. {
  444. #pragma unused(theMC, theParams)
  445.  
  446.     Boolean                isHandled = false;            // false => allow controller to process the action
  447.     WindowObject        myWindowObject = NULL;
  448.     
  449.     myWindowObject = (WindowObject)theRefCon;
  450.     if (myWindowObject == NULL)
  451.         return(isHandled);
  452.         
  453.     switch (theAction) {
  454.     
  455.         // handle window resizing
  456.         case mcActionControllerSizeChanged:
  457.             if (MCIsControllerAttached(theMC) == 1)
  458.                 QTFrame_SizeWindowToMovie(myWindowObject);
  459.             break;
  460.  
  461.         // handle idle events
  462.         case mcActionIdle:
  463.             QTApp_Idle((**myWindowObject).fWindow);
  464.             break;
  465.             
  466.         default:
  467.             break;
  468.             
  469.     } // switch (theAction)
  470.     
  471.     return(isHandled);    
  472. }
  473.  
  474.  
  475. #if TARGET_OS_MAC
  476. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  477. //
  478. // Apple Event functions.
  479. //
  480. // Use these functions to install handlers for Apple Events and to handle those events.
  481. //
  482. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  483.  
  484. //////////
  485. //
  486. // QTApp_InstallAppleEventHandlers 
  487. // Install handlers for Apple Events.
  488. //
  489. //////////
  490.  
  491. void QTApp_InstallAppleEventHandlers (void)
  492. {
  493.     long        myAttrs;
  494.     OSErr        myErr = noErr;
  495.     
  496.     // see whether the Apple Event Manager is available in the present operating environment;
  497.     // if it is, install handlers for the four required Apple Events
  498.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  499.     if (myErr == noErr) {
  500.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  501.             // create routine descriptors for the Apple event handlers
  502.             gHandleOpenAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenApplicationAppleEvent);
  503.             gHandleOpenDocAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenDocumentAppleEvent);
  504.             gHandlePrintDocAEUPP = NewAEEventHandlerUPP(QTApp_HandlePrintDocumentAppleEvent);
  505.             gHandleQuitAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleQuitApplicationAppleEvent);
  506.             
  507.             // install the handlers
  508.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  509.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  510.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  511.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  512.         }
  513.     }
  514. }
  515.         
  516.         
  517. //////////
  518. //
  519. // QTApp_HandleOpenApplicationAppleEvent 
  520. // Handle the open-application Apple Events.
  521. //
  522. //////////
  523.  
  524. PASCAL_RTN OSErr QTApp_HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  525. {
  526. #pragma unused(theMessage, theReply, theRefcon)
  527.     
  528.     // we don't need to do anything special when opening the application
  529.     return(noErr);
  530. }
  531.  
  532.  
  533. //////////
  534. //
  535. // QTApp_HandleOpenDocumentAppleEvent 
  536. // Handle the open-document Apple Events. This is based on Inside Macintosh: IAC, pp. 4-15f.
  537. //
  538. // Here we process an Open Documents AE only for files of type MovieFileType.
  539. //
  540. //////////
  541.  
  542. PASCAL_RTN OSErr QTApp_HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  543. {
  544. #pragma unused(theReply, theRefcon)
  545.  
  546.     long            myIndex;
  547.     long            myItemsInList;
  548.     AEKeyword        myKeyWd;
  549.     AEDescList          myDocList;
  550.     long            myActualSize;
  551.     DescType        myTypeCode;
  552.     FSSpec            myFSSpec;
  553.     OSErr            myIgnoreErr = noErr;
  554.     OSErr            myErr = noErr;
  555.     
  556.     // get the direct parameter and put it into myDocList
  557.     myDocList.dataHandle = NULL;
  558.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  559.     
  560.     // count the descriptor records in the list
  561.     if (myErr == noErr)
  562.         myErr = AECountItems(&myDocList, &myItemsInList);
  563.     else
  564.         myItemsInList = 0;
  565.     
  566.     // open each specified file
  567.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  568.         if (myErr == noErr) {
  569.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  570.             if (myErr == noErr) {
  571.                 FInfo        myFinderInfo;
  572.             
  573.                 // verify that the file type is MovieFileType; to do this, get the Finder information
  574.                 myErr = FSpGetFInfo(&myFSSpec, &myFinderInfo);    
  575.                 if (myErr == noErr) {
  576.                     if (myFinderInfo.fdType == MovieFileType)
  577.                         // we've got a movie file; just open it
  578.                         QTFrame_OpenMovieInWindow(NULL, &myFSSpec);
  579.                 }
  580.             }
  581.         }
  582.  
  583.     if (myDocList.dataHandle)
  584.         myIgnoreErr = AEDisposeDesc(&myDocList);
  585.     
  586.     // make sure we open the document in the foreground        
  587.     gAppInForeground = true;
  588.     return(myErr);
  589. }
  590.  
  591.  
  592. //////////
  593. //
  594. // QTApp_HandlePrintDocumentAppleEvent 
  595. // Handle the print-document Apple Events.
  596. //
  597. // NOT YET IMPLEMENTED.
  598. //
  599. //////////
  600.  
  601. PASCAL_RTN OSErr QTApp_HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  602. {
  603. #pragma unused(theMessage, theReply, theRefcon)
  604.  
  605.     return(errAEEventNotHandled);
  606. }
  607.  
  608.  
  609. //////////
  610. //
  611. // QTApp_HandleQuitApplicationAppleEvent 
  612. // Handle the quit-application Apple Events.
  613. //
  614. //////////
  615.  
  616. PASCAL_RTN OSErr QTApp_HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  617. {
  618. #pragma unused(theMessage, theReply, theRefcon)
  619.  
  620.     // close down the entire framework and application
  621.     QTFrame_QuitFramework();
  622.     return(noErr);
  623. }
  624. #endif // TARGET_OS_MAC
  625.  
  626.  
  627.